﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Office.OneNote;
using System.ComponentModel;

namespace Microsoft.Office.OneNote.XmlViewer.Controls
{
    public class HierarchyTreeView : TreeView
    {
        public void LoadHierarchy()
        {
            TreeNode[] nodes = (from n in OneNoteHierarchy.Current.Notebooks
                                select CreateNodeFor(n)).ToArray();
                
            BeginInvoke(new Action(() =>
            {
                BeginUpdate();
                Nodes.Add(new HierarchyXmlNode());
                Nodes.AddRange(nodes);
                EndUpdate();
            }));
        }

        [Browsable(false)]
        public OneNoteHierarchyObject SelectedHierarchyObject
        {
            get
            {
                IHierarchyTreeNode htn = SelectedNode as IHierarchyTreeNode;

                if (htn != null)
                {
                    return htn.GetHierarchyObject();
                }

                return null;
            }
        }

        [Browsable(false)]
        public bool IsHierarchyXmlNodeSelected
        {
            get { return SelectedNode is HierarchyXmlNode; } 
        }

        private static TreeNode CreateNodeFor(OneNoteObject obj)
        {
            OneNoteNotebook notebook = (obj as OneNoteNotebook);

            if (notebook != null)
            {
                return new NotebookNode(notebook);
            }

            OneNoteSectionBase sectionBase = (obj as OneNoteSectionBase);
            
            if (sectionBase != null)
            {
                return new SectionBaseNode(sectionBase);
            }

            return new PageNode((OneNotePage)(obj));
        }

        private interface IHierarchyTreeNode
        {
            OneNoteHierarchyObject GetHierarchyObject();
        }

        private sealed class HierarchyXmlNode : TreeNode
        {
            public HierarchyXmlNode()
            {
                Text = Properties.Resources.ShowHierarchyXml;
            }
        }

        private sealed class NotebookNode : TreeNode, IHierarchyTreeNode
        {
            private readonly OneNoteNotebook _notebook;

            public NotebookNode(OneNoteNotebook notebook)
            {
                _notebook = notebook;

                Text = notebook.Nickname;
                BackColor = notebook.Color.ToDrawingColor();

                foreach (OneNoteSectionBase sectionBase in notebook.Sections)
                {
                    Nodes.Add(CreateNodeFor(sectionBase));
                }

                Expand();
            }

            public OneNoteHierarchyObject GetHierarchyObject()
            {
                return _notebook;
            }
        }

        private sealed class SectionBaseNode : TreeNode, IHierarchyTreeNode
        {
            private readonly OneNoteSectionBase _sectionBase;

            public SectionBaseNode(OneNoteSectionBase sectionBase)
            {
                _sectionBase = sectionBase;

                Text = sectionBase.Name;
                BackColor = sectionBase.Color.ToDrawingColor();

                foreach (OneNoteSectionBase sec in sectionBase.Sections)
                {
                    Nodes.Add(CreateNodeFor(sec));
                }

                foreach (OneNotePage page in sectionBase.Pages)
                {
                    Nodes.Add(CreateNodeFor(page));
                }

            }

            public OneNoteHierarchyObject GetHierarchyObject()
            {
                return _sectionBase;
            }
        }

        private sealed class PageNode : TreeNode, IHierarchyTreeNode
        {
            private readonly OneNotePage _page;

            public PageNode(OneNotePage page)
            {
                _page = page;
                Text = page.Name;
                //BackColor = page.PageSettings.Color.ToDrawingColor();
            }


            public OneNoteHierarchyObject GetHierarchyObject()
            {
                return _page;
            }
        }
    }
}
